// xmlFormat.js -- nicely indents and escapes a string containing XML

/*
 * Format the server's xml response and html-escape it.
 */
function formatXmlResponse(xmlString) {
  return indent(htmlEscape(xmlString));
}


/* Indent and line break the XML content inside s, so that it's easier to
   read by the user */
function indent(xmlText) {
  var words = xmlText.split('&lt;');
  var indented = [];
  var indent = 0;
  var closedATag = false;
  var i = words[0] == '' ? 1 : 0; //skip first empty word
  var j, start;
  for(; i< words.length;++i) {
    j = 0;
    for(; j< words[i].length; ++j) {
      if (words[i].charAt(j) == ' ' || words[i].charAt(j) == '&') {
        break;
      }
    }
    start = words[i].charAt(0) == '/' ? 1 :0 ;
    s = (start==1?'/<b>':'<b>') + words[i].substr(start, j-start) + '</b>' + words[i].substr(j);
    if (start == 1) {
      indent -=2;
      if (closedATag) {
        indented.push('\n');
        addIndentation(indented, indent);
      }
      closedATag = true;
    } else if (words[i].length > 5 &&
        words[i].substring(words[i].length-5) != '/&gt;') {  
      // we are dealing with an opening tag
      closedATag = false;
      indented.push('\n');
      addIndentation(indented, indent);
      indent +=2;
    } else { // we are dealing with a 'degenerate' tag, like <link rel='xx' />
      indented.push('\n');  // always open new tags on a new line
      addIndentation(indented, indent);
    }
    indented.push('&lt;');
    indented.push(s);
  }
  return indented.join("");
}

function addIndentation(string, spaces) {
  for(var i=0; i<spaces;++i) {
    string.push(' ');
  }
}

/*
 * Html escapes &, <, and >
 */
function htmlEscape(s) {
  s = s.replace(/&/g, '&amp;');
  s = s.replace(/>/g, '&gt;');
  s = s.replace(/</g, '&lt;');
  return s;
}
